package com.eascs.web.sso.dubbo;

import java.util.Arrays;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.Filter;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcException;
import com.eascs.app.log.Logger;
import com.eascs.app.log.LoggerFactory;
import com.eascs.app.log.TraceLogger;
import com.eascs.site.session.SessionContext;

@Activate(group = Constants.CONSUMER, order = -10000 + 100)
public class SessionConsumerFilter implements Filter {
	public final static String REQUEST_SESSION_ID = "requestSessionId";
	private final Logger logger = LoggerFactory.getLogger(SessionConsumerFilter.class);

	public SessionConsumerFilter() {
		super();
	}

	@Override
	public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
		long start = System.currentTimeMillis();
		try {
			handle(invoker, invocation);
			Result result = invoker.invoke(invocation);
			return result;
		} finally {
			long elapsed = System.currentTimeMillis() - start;
			long timeout = invoker.getUrl().getMethodParameter(invocation.getMethodName(), "timeout", Integer.MAX_VALUE);
			logger.debug("dubbo consumer invoke end thread:{}, elapsed:{}ms ", Thread.currentThread().getId(), elapsed);
			if (invoker.getUrl() != null && (elapsed > timeout || (timeout == Integer.MAX_VALUE && TraceLogger.isTimeOut(elapsed, null)))) {
				logger.warn("dubbo consumer invoke time out. method: {} arguments: {} , url is {}, invoke elapsed {} ms.", invocation.getMethodName(), Arrays.toString(invocation.getArguments()), invoker.getUrl(), elapsed);
			}
		}
	}

	private void handle(Invoker<?> invoker, Invocation invocation) {
		if (null == SessionContext.get()) {
			return;
		}
		invocation.getAttachments().put(SessionConsumerFilter.REQUEST_SESSION_ID, SessionContext.get().getId());
		logger.debug("put dubbo Attachments requestSessionId={}", SessionContext.get().getId());
	}

}
